﻿
Public Module _signing

    Public Function shortmd5signing(ByVal s As String, Optional ByVal e As System.Text.Encoding = Nothing) As UInt32
        Static Dim md5calculator As Security.Cryptography.MD5 = Security.Cryptography.MD5.Create()
        Dim rtn As UInt32 = 0
        Dim i As UInt32
        Dim b As Byte() = Nothing

        If e Is Nothing Then
            e = encoding.utf8
        End If
        b = md5calculator.ComputeHash(e.GetBytes(s))

        For i = 0 To b.Length() - 1 Step b.Length() >> 2
            rtn <<= 8
            rtn += Convert.ToUInt32(b(i))
        Next

        Return rtn
    End Function

    Private ReadOnly signing8MaxMoveBits As Int32 = sizeof(Of UInt32)() * 8
    Public ReadOnly maxSigningIndex As Int32 = signing8MaxMoveBits << 2

    Public Function signing(Of t)(ByVal v As t, Optional ByVal signingIndex As Int32 = 16) As UInt32
        Select Case signingIndex
            Case 0 To signing8MaxMoveBits - 1
                Return signing8(v, signingIndex)
            Case signing8MaxMoveBits To signing8MaxMoveBits * 2 - 1
                Return signing9(v, signingIndex - signing8MaxMoveBits)
            Case signing8MaxMoveBits * 2 To signing8MaxMoveBits * 3 - 1
                Return signing10(v, signingIndex - signing8MaxMoveBits * 2)
            Case Else
                Return signing11(v, signingIndex Mod signing8MaxMoveBits)
        End Select
    End Function

    Private Function signing2(Of t)(ByVal v As t) As UInt32
        Return revert(Convert.ToString(v.GetHashCode())).GetHashCode()
    End Function

    Private Function signing3(Of t)(ByVal v As t) As UInt32
        Dim v2 As String = Convert.ToString(v.GetHashCode())
        Return revert(v2 + v2).GetHashCode()
    End Function

    Private Function signing4(Of t)(ByVal v As t) As UInt32
        Return shortmd5signing(Convert.ToString(v.GetHashCode()))
    End Function

    Private Function signing5(Of t)(ByVal v As t) As UInt32
        Dim v2 As UInt32 = signing8(v)
        Return Convert.ToString(v2).GetHashCode()
    End Function

    Private Function signing6(Of t)(ByVal v As t) As UInt32
        Return Convert.ToBase64String(encoding.utf8.GetBytes(Convert.ToString(v.GetHashCode))).GetHashCode
    End Function

    Private Function signing7(Of t)(ByVal v As t) As UInt32
        Return Convert.ToString(v.GetHashCode).GetHashCode
    End Function

    Private Function signing8(Of t)(ByVal v As t, Optional ByVal movebits As Int32 = 16) As UInt32
        If Not v Is Nothing Then
            Dim v2 As UInt32 = Convert.ToInt64(v.GetHashCode()) - minInt32
            movebits = movebits Mod signing8MaxMoveBits
            shift(v2, movebits)
            Return v2
        Else
            Return 0
        End If
    End Function

    Private Function signing9(Of t)(ByVal v As t, Optional ByVal movebits As Int32 = 16) As UInt32
        Return Not signing8(v, movebits)
    End Function

    Private Function signing10(Of t)(ByVal v As t, Optional ByVal movebits As Int32 = 16) As UInt32
        Return signing8(v, signing8MaxMoveBits - movebits)
    End Function

    Private Function signing11(Of t)(ByVal v As t, Optional ByVal movebits As Int32 = 16) As UInt32
        Return signing9(v, signing8MaxMoveBits - movebits)
    End Function

    Public Sub unittest()
        Dim s As String
        s = Console.ReadLine()
        While Not s Is Nothing
            Console.WriteLine(signing(s, rnd(0, maxSigningIndex, True)))
            s = Console.ReadLine()
        End While
    End Sub

    Public Sub unittestBase()
        Dim s As String
        s = Console.ReadLine()
        While Not s Is Nothing
            Console.WriteLine(signing(s))
            s = Console.ReadLine()
        End While
    End Sub

End Module
